﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.IO;

namespace Taurus.Platform.XML
{
    public abstract class BasePersistence<T>:IPersistence<T>
    {
        public abstract string FileName { get; }

        //为了调试方便将所有xml文件放置在同一目录下
        private string FileFullName { get { return "e:/config/"+FileName; } }

        protected XDocument _xd;

        public BasePersistence()
        {
            if (!File.Exists(FileFullName))
            {
                _xd = new XDocument(new XElement("root"));
                Save();
            }
            else
            {
                _xd = XDocument.Load(FileFullName);
            }
        }

        protected XElement Root 
        {
            get 
            {
                return _xd.Element("root"); 
            }
        }

        #region IPersistence<T> 成员

        public void Save()
        {
            _xd.Save(FileFullName);
        }

        public void Reload()
        {
            _xd = XDocument.Load(FileFullName);
        }

        public virtual void Insert(T item)
        {
            Root.Add(XChange(item));
        }

        public virtual void Delete(T item)
        {
            XElement el = GetEl(item);
            if (el != null)
            {
                el.Remove();
            }
        }

        public virtual void Update(T item)
        {
            Delete(item);
            Insert(item);
        }

        public abstract System.Xml.Linq.XElement GetEl(T item);

        public abstract T GetObject(string id);

        public virtual List<T> GetList(Func<T, bool> func)
        {
            List<T> list = new List<T>();
            foreach (var el in Root.Elements())
            {
                T item = XChange(el);
                if (func == null || func(item))
                {
                    list.Add(item);
                }
            }
            return list;
        }
       
        #endregion
        protected abstract XElement XChange(T item);

        protected abstract T XChange(XElement item);

    }
}
